/**
 *  Copyright (C) 2011  Thomas ROBIN
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package triseries;

import java.io.File;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * @author tshepo
 * 
 */
public class Scan extends Thread {

	private static final boolean DEBUG = (Main.debug || MyProperties.debug.equalsIgnoreCase("Scan"));
	private boolean movefiles;
	private Download old = null;

	Scan() {
	}

	@Override
	public void run() {
		if(DEBUG) System.err.println("Scan.run()");

		BetaSeriesXML.openConnection();
		List<String> sf = FileAcces.getSavedFile();
		Iterator<String> it = sf.iterator();
		movefiles = false;
		while (it.hasNext())
			processFile(new File(it.next().toString()));
		FileAcces.bakupSub();
		List<String> sf2 = FileAcces.getSavedSub();
		Collections.sort(sf2, String.CASE_INSENSITIVE_ORDER);
		Iterator<String> it2 = sf2.iterator();
		while (it2.hasNext()) {
			String s = it2.next().toString();
			if (s.endsWith(">>>VO")) {

				processSubtitle(new VideoFile(s.substring(0, s.length() - 5)),
						"VO");
			} else if (s.endsWith(">>>VF")) {

				processSubtitle(new VideoFile(s.substring(0, s.length() - 5)),
						"VF");
			} else {
				processSubtitle(new VideoFile(s));
			}
		}
		FileAcces.delBakupSub();
		for (String rep : MyProperties.nomRep) {
			if (rep.isEmpty())
				break;
			Repertoire r = new Repertoire(rep);
			movefiles = true;
			while (r.isNotEmpty()) {
				processFile(r.nextFile());
			}
		}

	}

	private void processSubtitle(VideoFile f) {
		if(DEBUG) System.err.println("Scan.processSubtitle("+f.getUrl()+")");
		if (!MyProperties.subs.equalsIgnoreCase("NONE")) {
			if (MyProperties.subs.equalsIgnoreCase("BOTH")) {
				processSubtitle(f, "VO");
				processSubtitle(f, "VF");
			} else {
				processSubtitle(f, MyProperties.subs);
			}
		}
	}

	private void processSubtitle(VideoFile f, String langue) {
		if(DEBUG) System.err.println("Scan.processSubtitle("+f.getUrl()+","+langue+")");
		/**
		 * Recherche du meilleur soutitre
		 */
		List<BTSubtitles> subsList = BetaSeriesXML.getSubtitlesUrl(f.getUrl(),
				f.getSeason(), f.getEpisode(), langue);
		if (subsList.isEmpty()) {
			if (DEBUG || MyProperties.verbose) {
				System.out.println("Aucun soutitres disponibles");
			}
			FileAcces.saveForLater(f.export() + ">>>" + langue + "\n");
			return;
		}
		/**
		 * Selection du meilleur soutitre
		 */
		String argplus;
		if (langue.equalsIgnoreCase("VO")) {
			argplus = " VO en ";
		} else {
			argplus = " VF fr ";
		}
		String[] attributes = (f.reste + argplus + MyProperties.arguments)
				.split(" |\\.|_");

		int bval = 0;
		BTSubtitles SelectedBTSubtitles = subsList.get(0);
		for (BTSubtitles bts : subsList) {
			int val = bts.bestMatch(attributes, f.getSeason(), f.getEpisode());
			if (val > bval) {
				bval = val;
				SelectedBTSubtitles = bts;
			}
		}
		if (SelectedBTSubtitles.bestSubtitle() == null
				|| SelectedBTSubtitles.bestSubtitle().isEmpty()) {
			if (DEBUG || MyProperties.verbose) {
				System.out.println("Aucun soutitres sélectionné");
			}
			FileAcces.saveForLater(f.export() + ">>>" + langue + "\n");
			return;
		}
		if (DEBUG || MyProperties.verbose) {
			System.out.println("Soutitre Sélectionné : "
					+ SelectedBTSubtitles.bestSubtitle());
		}

		/**
		 * Téléchargement et extraction du soutitre trouvé
		 */
		String newDirectory = MyProperties.nomRepDest[0] + File.separator
				+ f.path();
		String newName;
		if (MyProperties.subs.equalsIgnoreCase("BOTH")) {
			newName = f.basename()
					+ "."
					+ langue
					+ SelectedBTSubtitles.bestSubtitle()
							.substring(
									SelectedBTSubtitles.bestSubtitle()
											.lastIndexOf("."));
		} else {
			newName = f.basename()
					+ SelectedBTSubtitles.bestSubtitle()
							.substring(
									SelectedBTSubtitles.bestSubtitle()
											.lastIndexOf("."));
		}

		Download dl = new Download(SelectedBTSubtitles, newDirectory, newName,
				f.export(), old);
		dl.start();
		old = dl;
	}

	private void processFile(File fileName) {
		if (fileName == null) {
			return;
		}
		if(DEBUG) System.err.println("Scan.processFile("+fileName.getName()+")");

		/**
		 * Création VidéoFile";
		 */
		VideoFile f = new VideoFile(fileName);
		if (!f.isTVShow()) {
			return;
		}
		/**
		 * Recherche url";
		 */
		if (MyProperties.titleRename.containsKey(f.getShow())) {
			f.setShow(MyProperties.titleRename.get(f.getShow()));
		}
		if (f.getShow().length() > 2) {
			f.setUrl(BetaSeriesXML.getUrl(f));
		} else {
			f.setUrl("");
		}
		if (f.getUrl().isEmpty()) {
			if (f.getShow().matches(".*\\((((19)|(20))[0-9][0-9])\\)")) {
				f.setShow(f.getShow().substring(0, f.getShow().length() - 6)
						.trim());
			} else if (f.getShow().matches(".*(((19)|(20))[0-9][0-9])")) {
				f.setShow(f.getShow().substring(0, f.getShow().length() - 4)
						.trim());
			} else if (f.getShow().matches(".*UK")) {
				f.setShow(f.getShow().substring(0, f.getShow().length() - 2)
						.trim());
			} else if (f.getShow().matches(".*US")) {
				f.setShow(f.getShow().substring(0, f.getShow().length() - 2)
						.trim());
			} else {
				f.setShow(f.getShow() + " 20");
			}
			f.setUrl(BetaSeriesXML.getUrl(f));
		}
		if (!f.getUrl().isEmpty()) {
			/**
			 * Recherche episode";
			 */
			f.setTitle(BetaSeriesXML.getTitle(f.getUrl(), f));
			if (f.getTitle().isEmpty()) {
				/**
				 * Episode non trouvé , recherche encore l'url
				 */
				if (f.getShow().matches(".*\\((((19)|(20))[0-9][0-9])\\)")) {
					f.setShow(f.getShow()
							.substring(0, f.getShow().length() - 6).trim());
				} else if (f.getShow().matches(".*(((19)|(20))[0-9][0-9])")) {
					f.setShow(f.getShow()
							.substring(0, f.getShow().length() - 4).trim());
				} else {
					f.setShow(f.getShow() + " 20");
				}
				f.setUrl(BetaSeriesXML.getUrl(f));
				if (!f.getUrl().isEmpty()) {
					f.setTitle(BetaSeriesXML.getTitle(f.getUrl(), f));
				}
			}
		}

		if (f.getTitle().isEmpty()) {
			Main
					.processExeption("Aucun Episode trouvé pour "
							+ f.file().getName()
							+ "\n"
							+ " ajoutez manuellement le nom de la série aux préférences");
			return;
		}
		if (movefiles) {
			/**
			 * Episode trouvé - Déplace vidéo
			 */
			if (DEBUG || MyProperties.verbose) {
				System.out.println("move :" + MyProperties.nomRep[0]
						+ File.separator + f.file().getName() + "\nto : "
						+ MyProperties.nomRepDest[0] + File.separator
						+ f.toString());
			}
			if (!DEBUG) {
				MoveFile mf = new MoveFile(f.file().toString(),
						MyProperties.nomRepDest[0] + File.separator
								+ f.toString());
				mf.start();
			}
			/**
			 * Ajouter la série;
			 */
			if (!BetaSeriesXML.InShows(f.getUrl())) {
				BetaSeriesXML.addSerie(f.getUrl());
			}
			/**
			 * Marquer comme télécharger
			 */
			if (MyProperties.setDownloaded) {
				while (!BetaSeriesXML.setDownloaded(f.getUrl(), f.getSeason(),
						f.getEpisode()))
					;
			}
			/**
			 * Marquer comme vu
			 */
			if (MyProperties.setWatched
					&& BetaSeriesXML.isNotWatched(f.getUrl(), f.getSeason(), f
							.getEpisode())) {
				BetaSeriesXML.setWatched(f.getUrl(), f.getSeason(), f
						.getEpisode());
			}
		}

		/**
		 * Recherche Soustitre
		 */
		processSubtitle(f);

	}
}
